Skip to content

API | vorpal.command

Lewis Crichton edited this page May 7, 2018 · 17 revisions

Vorpal Command

The Command object is the building block for all commands in your CLI app. Running vorpal.command adds a new command and returns a new instance of the Command object, which holds a series of chainable methods for declaring and customizing your command.

API

vorpal.command(command[, description])

Adds a new command to your command line API. Returns a Command object.

vorpal
  .command('foo <requiredArg> [optionalArg]')
  .option('-v, --verbose', 'Print foobar instead.')
  .description('Outputs "bar".')
  .alias('foosball')
  .action(function(args, callback) {
    if (args.options.verbose) {
      this.log('foobar');
    } else {
      this.log('bar');
    }
    callback();
  });

When a command is executed by the user, the action method is fired, passing in the arguments and options given by the user, and a callback that ends the command when called.

Optional arguments
vorpal.command('foo [str]');
// $ foo bar -> {str: 'bar'}
Required arguments

When a required argument is not given the by user, the command's automated help menu is called.

vorpal.command('foo <str>');
// $ foo bar -> {str: 'bar'}
Variadic arguments

A variadic argument simply means the user can pass in multiple words to the argument, and the results are returned as an array of strings.

vorpal.command('foo [strings...]');
// $ foo bar and so on -> {strings: ['bar', `and`, `so`, `on`]}
Multiple arguments

Put the required arguments first, and variadic in the back.

vorpal.command('foo <required> [optional] [variadic...]');
// $ foo bar and so on 
// -> {required: 'bar', optional: 'and', variadic: [`so`, `on`]}
Optional description

You can optionally pass a description as the second parameter. This populates the automated help menu.

vorpal.command('foo', 'Outputs bar.'); 
$ help
  ...

    foo        Outputs bar.
Multi-word commands

Commands longer than one word will be grouped in the help menu.

vorpal.command('do this'); 
vorpal.command('do that and then <this>'); 
$ help
  ...

  Command Groups:

    do *     2 sub-commands.

.command.description(string)

If you don't pass a description into vorpal.command(...), you can use the description method as an alternative.

vorpal
  .command('foo')
  .description('outputs bar');

.command.alias(name[, names...])

Provides an alias to the command. If the user enters the alias, the original command will be fired.

vorpal
  .command('foo', 'Outputs bar.')
  .alias('foobar');
app~$ foobar
bar
app~$

The arguments (required or optional, variadic or not) declared on .command() will be applied to the aliases, you don't have to declare them again (in fact you must not).

vorpal
  .command('print [value]', 'Outputs the passed value.')
  .alias('echo');
app~$ echo something
something
app~$

.command.parse(parseFunction)

Parse and alter the raw command entered by the user before it is executing. Useful for things such as auto-appending pipes to the command under certain conditions.

vorpal
  .command('blabber', 'Outputs a whole bunch of text.')
  .parse(function (command, args) { 
    return command + ' | less';   
  });

.command.option(string[, description[, autocomplete]])

Extra options for the user. You can provide both short and long versions of an option, optional and required parameters. Results of an option are passed into the .action method's first parameter.

vorpal
  .command('print these options', 'Prints the options.')
  .option('-f, --force', 'Force file overwrite.')
  .option('-a, --amount <coffee>', 'Number of cups of coffee.')
  .option('-v, --verbosity [level]', 'Sets verbosity level.')
  .option('-A', 'Does amazing things.', ['Unicorn', 'Narwhal', 'Pixie'])
  .option('--amazing', 'Does amazing things')
  // ...
app~$ print these options -f --amount 8 -v -A --amazing
{ options: {
  force: true, 
  amount: 8, 
  verbosity: true, 
  A: true,
  amazing: true
}}

For details on implementing autocomplete, visit the Autocomplete page.

.command.types(object)

Explicitly types the data returned by given options.

vorpal
  .command('stringify')
  .option('-a, --amount <amt>', 'A number to stringify.')
  .types({
    string: ['a', 'amount']
  })
  .action(function (args, cb) {
    this.log(args.options);
    cb();
  });
app~$ stringify -a 7
{amount: '7'}         # would have otherwise been an integer

.command.hidden()

Makes the command invisible, though executable. Removes from all automated help menus.

vorpal
  .command('hidden', 'Secret command.')
  .hidden();

.command.remove()

Deletes a given command. Useful for getting rid of unwanted functionality when importing external extensions.

  const help = vorpal.find('help');
  if (help) { 
    help.remove();
  }

.command.help()

Overrides the auto-generated help method for a given command, which is invoked through [command] --help or [command] /?.

vorpal
  .command('foo')
  .help(function (args) {
    this.log('This command outputs "bar".');
  })
  .action(function(args, cb){
    this.log('bar');
  });

.command.validate(function)

Validates the user's input on a command before the action is fired. If invalid, the command is not executed.

Accepts a function that passes the user args in the same way as command.action.

  • If true is returned, the command is executed.
  • On returning false, the command is not executed and no message is sent to the user.
  • If a string is returned, it is logged and the command not executed.
vorpal.command('magic password <password>')
  .validate(function (args) {
    if (args.password === app.secret) {
      return true;
    } else {
      return 'Ah ah ah, you didn\'t say the magic word';
    }
  })
  .action(allowInside);

The function passed into command.validate is executed within the same context as vorpal.action, so you can use this.log as well for your own direct logging.

.command.autocomplete(array or object or function)

Registers a custom tabbed autocomplete result for this command.

vorpal
  .command('eat [food]')
  .autocomplete(['corn', 'steak', 'pasta'])
  .action(eat);

For advanced usage, visit the autocompletion page.

.command.autocompletion(function)

This command is deprecated. Use .command.autocomplete() instead.

Registers a custom tabbed autocompletion for this command.

vorpal
  .command("bake", "Bakes a meal.")
  .autocompletion(function(text, iteration, cb) {
    var meals = ["cookies", "pie", "cake"];
    if (iteration > 1) {
      cb(void 0, meals);
    } else {
      var match = this.match(text, meals);
      if (match) {
        cb(void 0, meals);
      } else {
        cb(void 0, void 0);
      }
    }
  })
  .action(...);
Explanation

If a user has typed part of a registered command, the default auto-completion will fill in the rest of the command:

node~$ co
node~$ cook

However, after the user has fully typed the command cook, you can now implement command-specific auto-completion:

node~$ bake coo            # tab is pressed
node~$ bake cookies        # tab is pressed again
cake  cookies  pie
node~$ bake cookies 

To further describe the implementation:

.command.action(function)

This is the action execution function of a given command. It passes in an arguments object and callback.

Actions are executed async and must either call the passed callback upon completion or return a Promise.

// As a callback:
command(...).action(function(args, cb){
  var self = this;
  doSomethingAsync(function(results){
    self.log(results);
    // If this is not called, Vorpal will not 
    // return its CLI prompt after command completion.
    cb();
  });
});

// As a newly created Promise:
command(...).action(function(args){
  return new Promise(function(resolve, reject) {
    if (skiesAlignTonight) {
      resolve();
    } else {
      reject("Better luck next time");
    }
  });
});

// Or as a pre-packaged promise of your app:
command(...).action(function(args, cb){
  return app.promisedAction(args.action);
});
Action Arguments

Given the following command:

vorpal
  .command('order pizza [type] [otherThings...]', 'Orders a type of food.')
  .option('-s, --size <size>', 'Size of pizza.')
  .option('-a, --anchovies', 'Include anchovies.')
  .option('-p, --pineapple', 'Include pineapple.')
  .option('-o', 'Include olives.')
  .option('-d, --delivery', 'Pizza should be delivered')
  .action(function(args, cb){
    this.log(args);
    cb();
  });

Args would be returned as follows:

$myapp~$ order pizza pepperoni some other args -pod --size "medium" --no-anchovies
{
  "type": "pepperoni",
  "otherThings": ["some", "other", "args"]
  "options": {
    "pineapple": true,
    "o": true,
    "delivery": true,
    "anchovies": false,
    "size": "medium",
  }
}
CommandInstance

The this in a Vorpal action exposes a CommandInstance object with several methods. See CommandInstance section for more details.

.command.cancel(function)

Triggers a function if the user cancels mid the command using [control] + c.

vorpal
  .command('foo')
  .action(function(args, cb){
    // ... long, complicated action
  })
  .cancel(function () {
    this.log('Didn\'t mother teach you to be patient?');
    // ... cleanup code, as the
    // command was halted mid-cycle.
  });

.command.allowUnknownOptions()

Allow for unknown options to be passed into a command. Disable options validation.

vorpal
  .command('foo')
  .allowUnknownOptions()
  .action(function(args, cb){
    // ...action
  });